import { Component, Label, UITransform, _decorator, instantiate } from "cc";
import { GameLayer, GameMgr } from "../GameMgr";
import { SnakeBody } from "./SnakeBody";
const { ccclass, property } = _decorator;

@ccclass("Snake")
export class Snake extends Component {

    data: kp_snake_snake;
    size: number;
    head: SnakeBody;
    bodyMap = new Map<number, SnakeBody>();
    labName: Label;

    needInit = true;

    onInit(data: kp_snake_snake) {
        if (this.needInit) {
            this.needInit = false;

            const { gameLayerMap, labNamePrefab } = GameMgr.ins;
            this.labName = instantiate(labNamePrefab).getComponent(Label);
            gameLayerMap.get(GameLayer.name).addChild(this.labName.node);
        }

        this.data = data;
        this.labName.string = data.name;
        return this;
    }

    addBody(data: kp_entity_snakeBody) {
        const body = SnakeBody.get(data.idx)
            .onInit(this, data, this.size);
        this.bodyMap.set(body.data.id, body);
        this.node.addChild(body.node);
        body.getComponent(UITransform).priority = Number.MAX_SAFE_INTEGER - data.idx;

        if (data.idx === 0) {
            this.head = body;
        }

        return body;
    }

    updateData(data: kp_snake_snake) {
        for (const key in data) {
            (this.data as any)[key] = (data as any)[key];
        }
        this.bodyMap.forEach(body => {
            if (data.colors !== undefined || data.ghost !== undefined) {
                body.updateColor();
            }
        });
    }

    updateBody(data: kp_entity_snakeBody) {
        this.bodyMap.get(data.id)?.updateData(data);
    }

    updateSize(size: number) {
        this.size = size;
        this.bodyMap.forEach(body => {
            body.updateSize(size);
        });
        const labSize = size / 150;
        this.labName.node.setScale(labSize, labSize);
    }

    removeBody(id: number) {
        const body = this.bodyMap.get(id);
        if (body) {
            if (body.data.idx === 0) {
                this.head = null;
            }
            body.onRemove();
            this.bodyMap.delete(id);
        }
    }

    protected update(dt: number): void {
        this.bodyMap.forEach(body => {
            body.update(dt);
        });
        if (this.head) {
            const { node: labNode } = this.labName;
            const { position, scale } = this.head.node;
            this.labName.enabled = true;
            labNode.setPosition(position.x, position.y + scale.x * 0.6);
        } else {
            this.labName.enabled = false;
        }
    }

}